# -*- coding: utf-8 -*-

"""
Module implementing MainWindow.
"""
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QMainWindow

from Ui_mainW import Ui_MainWindow

import wave
import time
import threading
import queue
import json
import urllib, urllib.request, pycurl
from pyaudio import PyAudio, paInt16

class MyThread(threading.Thread):
    def __init__(self, func, args, name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args
   
    def getResult(self):
        return self.res
    
    def run(self):
        print("starting", self.name, "at:", time.ctime())
        self.res = self.func(*self.args)
        print(self.name, "finished at:", time.ctime())
        

class MainWindow(QMainWindow, Ui_MainWindow, threading.Thread):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(MainWindow, self).__init__(parent)
        threading.Thread.__init__(self)
        self.setupUi(self)
        
        self.NUM_SAMPLES = 2000
        self.framerate = 8000
        self.sampwidth = 2               #两个字节
        self.channels = 1
        self.TIME = 2
        
        self.wav_queue = queue.Queue(1024)
        self.file_name_index = 1
        
    def run(self):
        print("starting", self.name, "at:", time.ctime())
        self.res = self.my_record
        print(self.name, "finished at:", time.ctime())
        
        
    def writeQ(self, queue, data):
        queue.put(data, 1)
        
    
    def readQ(self, queue):
        val = queue.get(1)
        return val
        
    #将语音信息写入wav文件
    def save_wave_file(self, filename, data):
        wf = wave.open(filename, "wb")
        wf.setnchannels(1)
        wf.setsampwidth(self.sampwidth)
        wf.setframerate(self.framerate)
        wf.writeframes(b"".join(data))
        wf.close()
        
    def my_record(self):#获取语音信息
        while True:
            pa = PyAudio()
            stream = pa.open(format = paInt16, channels = 1, rate = self.framerate, input = True, 
                             frames_per_buffer = self.NUM_SAMPLES)
            my_buf = []
            count = 0
            while count < self.TIME*8:   
                string_audio_data = stream.read(self.NUM_SAMPLES)
                my_buf.append(string_audio_data)
                count += 1
                print('.')
            if my_buf:
                if self.file_name_index<11:
                    pass
                else:
                    self.file_name_index = 1
                filename = str(self.file_name_index)+".wav"
                self.save_wave_file(filename=filename, data=my_buf)
                self.writeQ(queue=self.wav_queue, data=filename)
                self.file_name_index += 1
                print(filename, "saved")
    #       self.save_wave_file("01.wav", my_buf)
            else:
                print("file not saved!")
            stream.close()
        
    def dump_res(self, buf):
        print(buf)
        my_temp = json.loads(buf.decode("utf8"))
        if my_temp["err_no"]==3300:
            print("输入参数不正确")
        elif my_temp["err_no"]==3301:
            print("识别错误")
        elif my_temp["err_no"]==3302:
            print("验证失败")
        elif my_temp["err_no"]==3303:
            print("语音服务器后端问题")
        elif my_temp["err_no"]==3304:
            print("请求GPS过大，超过限额")
        elif my_temp["err_no"]==3305:
            print("产品当前在线请求次数已超过限额")
        else:
            self.my_list = my_temp['result']
            print(type(self.my_list))
            print(self.my_list[0])
            
            
    def get_token(self):
        apikey = "SFKLTpbG6ADUUpsHsNlYBc4t"
        secretkey = "76de3db62b0330086e4fc053a080ac36"
        auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id="+apikey+"&client_secret="+secretkey
        res = urllib.request.urlopen(auth_url)
        json_data = res.read()
        print(type(json_data))
        return json.loads(json_data.decode("utf8"))["access_token"]
    
    
    def use_cloud(self, token):
        while True:
            if self.wav_queue.qsize():
                filename = self.readQ(queue=self.wav_queue)
            else:
                continue
            fp = wave.open(filename, "rb")
            nf = fp.getnframes()            #获取文件采样点数量
            print("sample width:",fp.getsampwidth())
            print("framerate:",fp.getframerate())
            print("channels:",fp.getnchannels())
            f_len = nf*2                #文件长度
            audio_data = fp.readframes(nf)
            
            cuid = "xxxxxxxxxx"             #手机或电脑mac地址
            srv_url = "http://vop.baidu.com/server_api"+"?cuid="+cuid+"&token="+token
            http_header = [
                "Content-Type:audio/pcm;rate=8000",
                "Content-Length:%d"%f_len
            ]
            c = pycurl.Curl()
            c.setopt(pycurl.URL, str(srv_url))
            c.setopt(c.HTTPHEADER, http_header)
            c.setopt(c.POST, 1)
            c.setopt(c.CONNECTTIMEOUT, 80)
            c.setopt(c.TIMEOUT, 80)
            c.setopt(c.WRITEFUNCTION, self.dump_res)
            c.setopt(c.POSTFIELDS, audio_data)
            c.setopt(c.POSTFIELDSIZE, f_len)
            try:
                c.perform()
            except Exception as e:
                print(e)
            time.sleep(0.3)
            
                
    
    
    @pyqtSlot()#开始识别按钮
    def on_radioButton_clicked(self):
        """
        Slot documentation goes here.
        """
        
    
    @pyqtSlot()
    def on_radioButton_2_clicked(self):
        """
        Slot documentation goes here.
        """
        
    
    @pyqtSlot()
    def on_pushButton_clicked(self):
        """
        Slot documentation goes here.
        """
        self.my_record()
        self.use_cloud(self.get_token())
        self.textEdit.append(self.my_list[0])
    
    @pyqtSlot()
    def on_pushButton_2_clicked(self):
        """
        Slot documentation goes here.
        """
        
        
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ui = MainWindow()
    ui.setDaemon(True)
    ui.start()
    record_t = MyThread(ui.use_cloud, (ui.get_token(),), ui.use_cloud.__name__)
    record_t.setDaemon(True)            
    record_t.start()
    ui.show()
    sys.exit(app.exec_())
